package com.xie.smfs.entity;

import com.xie.smfs.item.GhostMoneyItem;
import com.xie.smfs.item.RedGhostCandleItem;
import com.xie.smfs.registry.ModItems;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageType;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.passive.PassiveEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Items;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.village.TradeOffer;
import net.minecraft.village.TradeOfferList;
import net.minecraft.village.Merchant;
import net.minecraft.world.World;
import net.minecraft.screen.MerchantScreenHandler;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GhostMerchantEntity extends GhostEntity implements Merchant {
    private static final Logger LOGGER = LoggerFactory.getLogger(GhostMerchantEntity.class);
    private static final int GHOST_DOMAIN_LEVEL = 0;

    private PlayerEntity customer;
    private TradeOfferList offers = new TradeOfferList();
    private boolean tradeOffersInitialized = false;

    // 构造函数
    public GhostMerchantEntity(EntityType<? extends GhostEntity> entityType, World world) {
        super(entityType, world);
        this.ghostLevel = 0;
        this.attackCooldown = 60;
        this.setPersistent();
        initMerchantAttributes();
        enableGhostDomain();
        setGhostDomainRadius(getDefaultGhostDomainRadius() * 1.2f);
    }

    // 初始化商人属性
    private void initMerchantAttributes() {
        this.getAttributeInstance(EntityAttributes.GENERIC_MAX_HEALTH).setBaseValue(30.0);
        this.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_SPEED).setBaseValue(0.3);
        this.getAttributeInstance(EntityAttributes.GENERIC_FOLLOW_RANGE).setBaseValue(16.0);
        this.setHealth(30.0F);
    }

    // 初始化交易列表
    private void initTradeOffers() {

        if (tradeOffersInitialized) return;

        offers = new TradeOfferList(); // 创建新的列表而不是清除


        // 添加交易项目
        ItemStack emeraldInput = new ItemStack(ModItems.GHOST_MONEY_3, 1);
        ItemStack candyOutput = new ItemStack(ModItems.GHOST_CANDY, 8);
        offers.add(new TradeOffer(emeraldInput, candyOutput, 12, 5, 0.05F));

        // 原有自定义物品交易
        ItemStack input = new ItemStack(ModItems.GHOST_MONEY_7, 1);
        ItemStack output = new ItemStack(ModItems.RUSTY_FRUIT_KNIFE, 1);
        offers.add(new TradeOffer(input, output, 12, 5, 0.05F));


        tradeOffersInitialized = true;


    }

    // 重写tick方法
    @Override
    public void tick() {
        super.tick();

        // 更新攻击冷却
        if (attackCooldown > 0) attackCooldown--;

        // 确保交易列表仅在服务器端初始化
        if (!getWorld().isClient && !tradeOffersInitialized) {
            initTradeOffers();
        }

        // 独立执行杀人规则检查（不依赖父类的tick逻辑）
        if (!getWorld().isClient && !isSuppressed() && !isDeadlocked() && isKillingRulesEnabled() && customer == null) {

            for (PlayerEntity player : getWorld().getPlayers()) {

                boolean attackable = shouldAttackPlayer(player);
                boolean reachable = canReachPlayer(player);

                if (attackable && reachable) {

                    executeAttack(player);
                    break; // 一次只攻击一个玩家
                }
            }
        }

        // 随机移动逻辑
        if (!getWorld().isClient && !isSuppressed() && !isDeadlocked() && !movementDisabled) {
            if (this.age % 200 == 0 && getGhostRandom().nextBoolean()) {
                double radius = 8.0;
                double x = this.getX() + (getGhostRandom().nextDouble() - 0.5) * radius * 2;
                double z = this.getZ() + (getGhostRandom().nextDouble() - 0.5) * radius * 2;
                this.getNavigation().startMovingTo(x, this.getY(), z, 0.8);
            }
        }
    }

    // 检查是否可以到达玩家
    private boolean canReachPlayer(PlayerEntity player) {
        double distanceSq = squaredDistanceTo(player);
        return distanceSq <= 256.0;
    }

    // 重写杀人规则: 攻击没有鬼钱的玩家
    @Override
    protected boolean shouldAttackPlayer(PlayerEntity player) {
        // 检查基本条件
        if (isSuppressed() || isDeadlocked() || !isKillingRulesEnabled() || attackCooldown > 0) {
            return false;
        }

        // 检查距离
        if (squaredDistanceTo(player) > 1024.0) { // 32格距离的平方
            return false;
        }

        // 检查红蜡烛保护
        if (RedGhostCandleItem.isHoldingCandle(player)) {
            return false;
        }

        // 检查是否有鬼钱
        boolean hasGhostMoney = false;
        for (int i = 0; i < player.getInventory().size(); i++) {
            ItemStack stack = player.getInventory().getStack(i);
            if (stack.getItem() instanceof GhostMoneyItem && stack.getCount() > 0) {
                hasGhostMoney = true;
                break;
            }
        }

        return !hasGhostMoney;
    }

    // 执行攻击
    @Override
    protected void executeAttack(PlayerEntity player) {
        // 瞬移到玩家面前
        this.teleport(player.getX(), player.getY(), player.getZ());
        // 获取 mob 伤害类型的注册表项
        RegistryEntry<DamageType> mobDamageType = this.getWorld().getRegistryManager().get(RegistryKeys.DAMAGE_TYPE).getEntry(RegistryKey.of(RegistryKeys.DAMAGE_TYPE, new Identifier("smfs", "ghost"))).orElseThrow(() -> new IllegalStateException("MOB_ATTACK damage type not found"));
        // 创建伤害源
        DamageSource damageSource = new DamageSource(mobDamageType, this);
        player.addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, 20, 1));

        player.damage(damageSource, Float.MAX_VALUE);
        this.attackCooldown = 20; // 重置攻击冷却
        }


    // 重写交互方法打开交易界面
    @Override
    public ActionResult interactMob(PlayerEntity player, Hand hand) {
        if (this.getWorld().isClient) {
            return ActionResult.SUCCESS;
        } else if (player.isSneaking()) {
            return super.interactMob(player, hand);
        } else {
            // 确保交易列表已初始化
            if (!tradeOffersInitialized) {
                initTradeOffers();
            }

            if (this.getCustomer() != player) {
                this.setCustomer(player);
                player.openHandledScreen(new NamedScreenHandlerFactory() {
                    @Override
                    public ScreenHandler createMenu(int syncId, PlayerInventory inventory, PlayerEntity player) {
                        return new MerchantScreenHandler(syncId, inventory, GhostMerchantEntity.this);
                    }

                    @Override
                    public Text getDisplayName() {
                        return GhostMerchantEntity.this.getDisplayName();
                    }
                });

                if (!getWorld().isClient) {

                }
            }
            return ActionResult.CONSUME;
        }
    }

    // Merchant 接口实现 - 这是关键修复部分
    @Override
    public TradeOfferList getOffers() {


        // 在客户端，直接返回当前列表（服务器会通过数据包同步）
        if (getWorld().isClient) {
            return offers;
        }

        // 服务器端：确保交易已初始化且列表非空
        if (!tradeOffersInitialized || offers.isEmpty()) {

            initTradeOffers();
        }


        return offers;
    }

    @Override
    public void setOffersFromServer(TradeOfferList offers) {
        if (offers != null) {
            this.offers = offers;
            tradeOffersInitialized = true;

        }
    }

    @Override
    public void setCustomer(PlayerEntity customer) {
        this.customer = customer;
    }

    @Override
    public PlayerEntity getCustomer() {
        return customer;
    }

    @Override
    public void trade(TradeOffer offer) {
        offer.use();
    }

    @Override
    public void onSellingItem(ItemStack stack) {}

    @Override
    public int getExperience() {
        return 0;
    }

    @Override
    public void setExperienceFromServer(int experience) {
        // 从服务器接收经验值
    }

    @Override
    public boolean isLeveledMerchant() {
        return false;
    }

    @Override
    public SoundEvent getYesSound() {
        return null;
    }

    @Override
    public boolean isClient() {
        return getWorld().isClient;
    }

    // 获取商人纹理的方法
    public Identifier getMerchantTexture() {
        return new Identifier("smfs", "textures/entity/ghost_merchant.png");
    }

    // 辅助方法：获取默认鬼域半径
    protected float getDefaultGhostDomainRadius() {
        return 10.0f + (this.ghostLevel * 2.0f);
    }

    // 添加数据同步方法
    @Override
    public void writeCustomDataToNbt(NbtCompound nbt) {
        super.writeCustomDataToNbt(nbt);
        // 保存交易数据
        NbtList offersNbt = new NbtList();
        for (TradeOffer offer : this.offers) {
            NbtCompound offerNbt = new NbtCompound();
            offer.toNbt();
            offersNbt.add(offerNbt);
        }
        nbt.put("Offers", offersNbt);
        nbt.putBoolean("TradeOffersInitialized", tradeOffersInitialized);
    }

    @Override
    public void readCustomDataFromNbt(NbtCompound nbt) {
        super.readCustomDataFromNbt(nbt);
        // 读取交易数据
        if (nbt.contains("Offers", NbtElement.LIST_TYPE)) {
            NbtList offersNbt = nbt.getList("Offers", NbtElement.COMPOUND_TYPE);
            this.offers = new TradeOfferList();
            for (int i = 0; i < offersNbt.size(); i++) {
                NbtCompound offerNbt = offersNbt.getCompound(i);
                TradeOffer offer = new TradeOffer(offerNbt);
                this.offers.add(offer);
            }
        }
        if (nbt.contains("TradeOffersInitialized")) {
            this.tradeOffersInitialized = nbt.getBoolean("TradeOffersInitialized");
        }
    }
}